/*     */ package com.zimbra.cs.filter;
/*     */ 
/*     */ import com.google.common.annotations.VisibleForTesting;
/*     */ import com.google.common.collect.Sets;
/*     */ import com.zimbra.client.ZFolder;
/*     */ import com.zimbra.client.ZMailbox;
/*     */ import com.zimbra.client.ZMailbox.Options;
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.mime.shim.JavaMailInternetAddress;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.util.ArrayUtil;
/*     */ import com.zimbra.common.util.CharsetUtil;
/*     */ import com.zimbra.common.util.L10nUtil;
/*     */ import com.zimbra.common.util.L10nUtil.MsgKey;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.Pair;
/*     */ import com.zimbra.common.util.StringUtil;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.common.zmime.ZInternetHeader;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.filter.jsieve.ActionFlag;
/*     */ import com.zimbra.cs.mailbox.DeliveryContext;
/*     */ import com.zimbra.cs.mailbox.DeliveryOptions;
/*     */ import com.zimbra.cs.mailbox.Flag;
/*     */ import com.zimbra.cs.mailbox.Flag.FlagInfo;
/*     */ import com.zimbra.cs.mailbox.Folder;
/*     */ import com.zimbra.cs.mailbox.Folder.FolderOptions;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailSender;
/*     */ import com.zimbra.cs.mailbox.MailSender.DsnNotifyOption;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.Message;
/*     */ import com.zimbra.cs.mailbox.Mountpoint;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.mime.MPartInfo;
/*     */ import com.zimbra.cs.mime.Mime;
/*     */ import com.zimbra.cs.mime.Mime.FixedMimeMessage;
/*     */ import com.zimbra.cs.mime.ParsedMessage;
/*     */ import com.zimbra.cs.service.AuthProvider;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.util.AccountUtil;
/*     */ import com.zimbra.cs.util.JMSession;
/*     */ import java.io.IOException;
/*     */ import java.io.UnsupportedEncodingException;
/*     */ import java.util.Arrays;
/*     */ import java.util.Collection;
/*     */ import java.util.Date;
/*     */ import java.util.Enumeration;
/*     */ import java.util.HashMap;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ import javax.mail.Address;
/*     */ import javax.mail.Header;
/*     */ import javax.mail.Message.RecipientType;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.internet.InternetAddress;
/*     */ import javax.mail.internet.MimeMessage;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class FilterUtil
/*     */ {
/*     */   public static final String HEADER_FORWARDED = "X-Zimbra-Forwarded";
/*     */   public static final String HEADER_CONTENT_TYPE = "Content-Type";
/*     */   public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
/*     */   
/*     */   public static String escape(String s)
/*     */   {
/*  85 */     if ((s == null) || (s.length() == 0)) {
/*  86 */       return s;
/*     */     }
/*  88 */     s = s.replace("\\", "\\\\");
/*  89 */     s = s.replace("\"", "\\\"");
/*  90 */     return s;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static <T> int addToMap(Map<Integer, T> map, int initialKey, T value)
/*     */   {
/* 102 */     int i = initialKey;
/*     */     for (;;) {
/* 104 */       if (!map.containsKey(Integer.valueOf(i))) {
/* 105 */         map.put(Integer.valueOf(i), value);
/* 106 */         return i;
/*     */       }
/* 108 */       i++;
/*     */     }
/*     */   }
/*     */   
/*     */   public static int getIndex(Element actionElement) {
/* 113 */     String s = actionElement.getAttribute("index", "0");
/*     */     try {
/* 115 */       return Integer.parseInt(s);
/*     */     } catch (NumberFormatException e) {
/* 117 */       ZimbraLog.soap.warn("Unable to parse index value %s for element %s.  Ignoring order.", new Object[] { s, actionElement.getName() });
/*     */     }
/* 119 */     return 0;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static int parseSize(String sizeString)
/*     */   {
/* 132 */     if ((sizeString == null) || (sizeString.length() == 0)) {
/* 133 */       return 0;
/*     */     }
/* 135 */     sizeString = sizeString.toUpperCase();
/* 136 */     int multiplier = 1;
/* 137 */     if (sizeString.endsWith("K")) {
/* 138 */       sizeString = sizeString.substring(0, sizeString.length() - 1);
/* 139 */       multiplier = 1024;
/* 140 */     } else if (sizeString.endsWith("M")) {
/* 141 */       sizeString = sizeString.substring(0, sizeString.length() - 1);
/* 142 */       multiplier = 1048576;
/* 143 */     } else if (sizeString.endsWith("G")) {
/* 144 */       sizeString = sizeString.substring(0, sizeString.length() - 1);
/* 145 */       multiplier = 1073741824;
/*     */     }
/* 147 */     return Integer.parseInt(sizeString) * multiplier;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static ItemId addMessage(DeliveryContext context, Mailbox mbox, ParsedMessage pm, String recipient, String folderPath, boolean noICal, int flags, String[] tags, int convId, OperationContext octxt)
/*     */     throws ServiceException
/*     */   {
/* 158 */     Pair<Folder, String> folderAndPath = mbox.getFolderByPathLongestMatch(octxt, 1, folderPath);
/*     */     
/* 160 */     Folder folder = (Folder)folderAndPath.getFirst();
/* 161 */     String remainingPath = (String)folderAndPath.getSecond();
/* 162 */     ZimbraLog.filter.debug("Attempting to file to %s, remainingPath=%s.", new Object[] { folder, remainingPath });
/*     */     
/* 164 */     if ((folder instanceof Mountpoint)) {
/* 165 */       Mountpoint mountpoint = (Mountpoint)folder;
/* 166 */       ZMailbox remoteMbox = getRemoteZMailbox(mbox, mountpoint);
/*     */       
/*     */ 
/* 169 */       String remoteAccountId = mountpoint.getOwnerId();
/* 170 */       ItemId id = mountpoint.getTarget();
/* 171 */       ZFolder remoteFolder = remoteMbox.getFolderById(id.toString());
/* 172 */       if ((remoteFolder != null) && 
/* 173 */         (remainingPath != null)) {
/* 174 */         remoteFolder = remoteFolder.getSubFolderByPath(remainingPath);
/* 175 */         if (remoteFolder == null) {
/* 176 */           String msg = String.format("Subfolder %s of mountpoint %s does not exist.", new Object[] { remainingPath, mountpoint.getName() });
/*     */           
/* 178 */           throw ServiceException.FAILURE(msg, null);
/*     */         }
/*     */       }
/*     */       
/*     */ 
/*     */ 
/* 184 */       if (remoteFolder != null) {
/*     */         byte[] content;
/*     */         try {
/* 187 */           content = pm.getRawData();
/*     */         } catch (Exception e) {
/* 189 */           throw ServiceException.FAILURE("Unable to get message content", e);
/*     */         }
/* 191 */         String msgId = remoteMbox.addMessage(remoteFolder.getId(), Flag.toString(flags), null, 0L, content, false);
/*     */         
/* 193 */         return new ItemId(msgId, remoteAccountId);
/*     */       }
/* 195 */       String msg = String.format("Unable to find remote folder %s for mountpoint %s.", new Object[] { remainingPath, mountpoint.getName() });
/*     */       
/* 197 */       throw ServiceException.FAILURE(msg, null);
/*     */     }
/*     */     
/* 200 */     if (!StringUtil.isNullOrEmpty(remainingPath))
/*     */     {
/* 202 */       ZimbraLog.filter.info("Could not find folder %s.  Automatically creating it.", new Object[] { folderPath });
/*     */       
/* 204 */       folder = mbox.createFolder(octxt, folderPath, new Folder.FolderOptions().setDefaultView(MailItem.Type.MESSAGE));
/*     */     }
/*     */     try {
/* 207 */       DeliveryOptions dopt = new DeliveryOptions().setFolderId(folder).setNoICal(noICal);
/* 208 */       dopt.setFlags(flags).setTags(tags).setConversationId(convId).setRecipientEmail(recipient);
/* 209 */       Message msg = mbox.addMessage(octxt, pm, dopt, context);
/* 210 */       if (msg == null) {
/* 211 */         return null;
/*     */       }
/* 213 */       return new ItemId(msg);
/*     */     }
/*     */     catch (IOException e) {
/* 216 */       throw ServiceException.FAILURE("Unable to add message", e);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static ZMailbox getRemoteZMailbox(Mailbox localMbox, Mountpoint mountpoint)
/*     */     throws ServiceException
/*     */   {
/* 228 */     AuthToken authToken = null;
/* 229 */     OperationContext opCtxt = localMbox.getOperationContext();
/* 230 */     if (opCtxt != null) {
/* 231 */       authToken = AuthToken.getCsrfUnsecuredAuthToken(opCtxt.getAuthToken());
/*     */     }
/* 233 */     if (authToken == null) {
/* 234 */       authToken = AuthProvider.getAuthToken(localMbox.getAccount());
/*     */     }
/*     */     
/*     */ 
/* 238 */     Account account = Provisioning.getInstance().get(Key.AccountBy.id, mountpoint.getOwnerId());
/* 239 */     ZMailbox.Options zoptions = new ZMailbox.Options(authToken.toZAuthToken(), AccountUtil.getSoapUri(account));
/* 240 */     zoptions.setNoSession(true);
/* 241 */     zoptions.setTargetAccount(account.getId());
/* 242 */     zoptions.setTargetAccountBy(Key.AccountBy.id);
/* 243 */     return ZMailbox.getMailbox(zoptions);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static void redirect(OperationContext octxt, Mailbox sourceMbox, MimeMessage msg, String destinationAddress)
/*     */     throws ServiceException
/*     */   {
/*     */     MimeMessage outgoingMsg;
/*     */     
/*     */     try
/*     */     {
/* 255 */       if (!isMailLoop(sourceMbox, msg)) {
/* 256 */         MimeMessage outgoingMsg = new Mime.FixedMimeMessage(msg);
/* 257 */         Mime.recursiveRepairTransferEncoding(outgoingMsg);
/* 258 */         outgoingMsg.addHeader("X-Zimbra-Forwarded", sourceMbox.getAccount().getName());
/* 259 */         outgoingMsg.saveChanges();
/*     */       } else {
/* 261 */         String error = String.format("Detected a mail loop for message %s.", new Object[] { Mime.getMessageID(msg) });
/* 262 */         throw ServiceException.FAILURE(error, null);
/*     */       }
/*     */     } catch (MessagingException e) {
/*     */       try {
/* 266 */         outgoingMsg = createRedirectMsgOnError(msg);
/* 267 */         ZimbraLog.filter.info("Message format error detected.  Wrapper class in use.  %s", new Object[] { e.toString() });
/*     */       } catch (MessagingException again) {
/* 269 */         throw ServiceException.FAILURE("Message format error detected.  Workaround failed.", again);
/*     */       }
/*     */     } catch (IOException e) {
/*     */       try {
/* 273 */         outgoingMsg = createRedirectMsgOnError(msg);
/* 274 */         ZimbraLog.filter.info("Message format error detected.  Wrapper class in use.  %s", new Object[] { e.toString() });
/*     */       } catch (MessagingException me) {
/* 276 */         throw ServiceException.FAILURE("Message format error detected.  Workaround failed.", me);
/*     */       }
/*     */     }
/*     */     
/* 280 */     MailSender sender = sourceMbox.getMailSender().setSaveToSent(false).setRedirectMode(true).setSkipHeaderUpdate(true);
/*     */     try
/*     */     {
/* 283 */       if (Provisioning.getInstance().getLocalServer().isMailRedirectSetEnvelopeSender()) {
/* 284 */         if ((isDeliveryStatusNotification(msg)) && (LC.filter_null_env_sender_for_dsn_redirect.booleanValue())) {
/* 285 */           sender.setEnvelopeFrom("<>");
/* 286 */           sender.setDsnNotifyOptions(new MailSender.DsnNotifyOption[] { MailSender.DsnNotifyOption.NEVER });
/*     */         }
/*     */         else {
/* 289 */           Account account = sourceMbox.getAccount();
/* 290 */           sender.setEnvelopeFrom(account.getName());
/*     */         }
/*     */       } else {
/* 293 */         Address from = (Address)ArrayUtil.getFirstElement(outgoingMsg.getFrom());
/* 294 */         if (from != null) {
/* 295 */           String address = ((InternetAddress)from).getAddress();
/* 296 */           sender.setEnvelopeFrom(address);
/*     */         }
/*     */       }
/* 299 */       sender.setRecipients(new String[] { destinationAddress });
/* 300 */       sender.sendMimeMessage(octxt, sourceMbox, outgoingMsg);
/*     */     } catch (MessagingException e) {
/* 302 */       ZimbraLog.filter.warn("Envelope sender will be set to the default value.", e);
/*     */     }
/*     */   }
/*     */   
/*     */   private static boolean isDeliveryStatusNotification(MimeMessage msg) throws MessagingException
/*     */   {
/* 308 */     String envelopeSender = msg.getHeader("Return-Path", null);
/* 309 */     String ct = Mime.getContentType(msg, "text/plain");
/* 310 */     ZimbraLog.filter.debug("isDeliveryStatusNotification(): Return-Path=%s, Auto-Submitted=%s, Content-Type=%s.", new Object[] { envelopeSender, msg.getHeader("Auto-Submitted", null), ct });
/*     */     
/*     */ 
/* 313 */     if ((StringUtil.isNullOrEmpty(envelopeSender)) || (envelopeSender.equals("<>"))) {
/* 314 */       return true;
/*     */     }
/* 316 */     if (Mime.isAutoSubmitted(msg)) {
/* 317 */       return true;
/*     */     }
/* 319 */     if (ct.equals("multipart/report")) {
/* 320 */       return true;
/*     */     }
/* 322 */     return false;
/*     */   }
/*     */   
/*     */   public static void reply(OperationContext octxt, Mailbox mailbox, ParsedMessage parsedMessage, String bodyTemplate) throws MessagingException, ServiceException
/*     */   {
/* 327 */     MimeMessage mimeMessage = parsedMessage.getMimeMessage();
/* 328 */     if (isMailLoop(mailbox, mimeMessage)) {
/* 329 */       String error = String.format("Detected a mail loop for message %s.", new Object[] { Mime.getMessageID(mimeMessage) });
/* 330 */       throw ServiceException.FAILURE(error, null);
/*     */     }
/* 332 */     if (isDeliveryStatusNotification(mimeMessage)) {
/* 333 */       ZimbraLog.filter.debug("Not auto-replying to a DSN message");
/* 334 */       return;
/*     */     }
/*     */     
/* 337 */     Account account = mailbox.getAccount();
/* 338 */     MimeMessage replyMsg = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
/*     */     
/* 340 */     for (String headerFwdAccountName : Mime.getHeaders(mimeMessage, "X-Zimbra-Forwarded")) {
/* 341 */       replyMsg.addHeader("X-Zimbra-Forwarded", headerFwdAccountName);
/*     */     }
/* 343 */     replyMsg.addHeader("X-Zimbra-Forwarded", account.getName());
/*     */     
/* 345 */     String to = mimeMessage.getHeader("Reply-To", null);
/* 346 */     if (StringUtil.isNullOrEmpty(to))
/* 347 */       to = Mime.getSender(mimeMessage);
/* 348 */     if (StringUtil.isNullOrEmpty(to))
/* 349 */       throw new MessagingException("Can't locate the address to reply to");
/* 350 */     replyMsg.setRecipient(Message.RecipientType.TO, new JavaMailInternetAddress(to));
/*     */     
/* 352 */     String subject = mimeMessage.getSubject();
/* 353 */     if (subject == null) {
/* 354 */       subject = "";
/*     */     }
/* 356 */     String replySubjectPrefix = L10nUtil.getMessage(L10nUtil.MsgKey.replySubjectPrefix, account.getLocale(), new Object[0]);
/* 357 */     if (!subject.toLowerCase().startsWith(replySubjectPrefix.toLowerCase())) {
/* 358 */       subject = replySubjectPrefix + " " + subject;
/*     */     }
/* 360 */     replyMsg.setSubject(subject, getCharset(account, subject));
/*     */     
/* 362 */     Map<String, String> vars = getVarsMap(mailbox, parsedMessage, mimeMessage);
/* 363 */     String body = StringUtil.fillTemplate(bodyTemplate, vars);
/* 364 */     replyMsg.setText(body, getCharset(account, body));
/*     */     
/* 366 */     String origMsgId = mimeMessage.getMessageID();
/* 367 */     if (!StringUtil.isNullOrEmpty(origMsgId))
/* 368 */       replyMsg.setHeader("In-Reply-To", origMsgId);
/* 369 */     replyMsg.setSentDate(new Date());
/* 370 */     replyMsg.saveChanges();
/*     */     
/* 372 */     MailSender mailSender = mailbox.getMailSender();
/* 373 */     mailSender.setReplyType(MailSender.MSGTYPE_REPLY);
/* 374 */     mailSender.setDsnNotifyOptions(new MailSender.DsnNotifyOption[] { MailSender.DsnNotifyOption.NEVER });
/* 375 */     mailSender.sendMimeMessage(octxt, mailbox, replyMsg);
/*     */   }
/*     */   
/*     */   public static void notify(OperationContext octxt, Mailbox mailbox, ParsedMessage parsedMessage, String emailAddr, String subjectTemplate, String bodyTemplate, int maxBodyBytes, List<String> origHeaders)
/*     */     throws MessagingException, ServiceException
/*     */   {
/* 381 */     MimeMessage mimeMessage = parsedMessage.getMimeMessage();
/* 382 */     if (isMailLoop(mailbox, mimeMessage)) {
/* 383 */       String error = String.format("Detected a mail loop for message %s.", new Object[] { Mime.getMessageID(mimeMessage) });
/* 384 */       throw ServiceException.FAILURE(error, null);
/*     */     }
/*     */     
/* 387 */     Account account = mailbox.getAccount();
/* 388 */     MimeMessage notification = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
/*     */     
/* 390 */     for (String headerFwdAccountName : Mime.getHeaders(mimeMessage, "X-Zimbra-Forwarded")) {
/* 391 */       notification.addHeader("X-Zimbra-Forwarded", headerFwdAccountName);
/*     */     }
/*     */     
/* 394 */     notification.addHeader("X-Zimbra-Forwarded", account.getName());
/* 395 */     MailSender mailSender = mailbox.getMailSender().setSaveToSent(false);
/*     */     
/* 397 */     Map<String, String> vars = getVarsMap(mailbox, parsedMessage, mimeMessage);
/* 398 */     if ((origHeaders == null) || (origHeaders.isEmpty()))
/*     */     {
/* 400 */       notification.setRecipient(Message.RecipientType.TO, new JavaMailInternetAddress(emailAddr));
/* 401 */       notification.setSentDate(new Date());
/* 402 */       if (!StringUtil.isNullOrEmpty(subjectTemplate)) {
/* 403 */         String subject = StringUtil.fillTemplate(subjectTemplate, vars);
/* 404 */         notification.setSubject(subject, getCharset(account, subject));
/*     */       }
/*     */     } else {
/* 407 */       if ((origHeaders.size() == 1) && ("*".equals(origHeaders.get(0))))
/*     */       {
/* 409 */         Enumeration enumeration = mimeMessage.getAllHeaders();
/* 410 */         while (enumeration.hasMoreElements()) {
/* 411 */           Header header = (Header)enumeration.nextElement();
/* 412 */           if ((!StringUtil.equal(header.getName(), "X-Zimbra-Forwarded")) && 
/*     */           
/*     */ 
/*     */ 
/* 416 */             (!StringUtil.equal(header.getName(), "Content-Type")) && (!StringUtil.equal(header.getName(), "Content-Disposition")))
/*     */           {
/*     */ 
/*     */ 
/*     */ 
/* 421 */             notification.addHeader(header.getName(), header.getValue());
/*     */           }
/*     */         }
/*     */       } else {
/* 425 */         Set<String> headersToCopy = Sets.newHashSet(origHeaders);
/* 426 */         boolean copySubject = false;
/* 427 */         for (String header : headersToCopy) {
/* 428 */           if ("Subject".equalsIgnoreCase(header)) {
/* 429 */             copySubject = true;
/*     */           }
/* 431 */           if (!StringUtil.equal(header, "X-Zimbra-Forwarded"))
/*     */           {
/*     */ 
/* 434 */             String[] hdrVals = mimeMessage.getHeader(header);
/* 435 */             if (hdrVals != null)
/*     */             {
/*     */ 
/* 438 */               for (String hdrVal : hdrVals)
/* 439 */                 notification.addHeader(header, hdrVal); }
/*     */           }
/*     */         }
/* 442 */         if ((!copySubject) && (!StringUtil.isNullOrEmpty(subjectTemplate))) {
/* 443 */           String subject = StringUtil.fillTemplate(subjectTemplate, vars);
/* 444 */           notification.setSubject(subject, getCharset(account, subject));
/*     */         }
/*     */       }
/* 447 */       mailSender.setRedirectMode(true);
/* 448 */       mailSender.setRecipients(new String[] { emailAddr });
/*     */     }
/*     */     
/* 451 */     String body = StringUtil.fillTemplate(bodyTemplate, vars);
/* 452 */     body = truncateBodyIfRequired(body, maxBodyBytes);
/* 453 */     notification.setText(body, getCharset(account, body));
/* 454 */     notification.saveChanges();
/*     */     
/* 456 */     if (isDeliveryStatusNotification(mimeMessage)) {
/* 457 */       mailSender.setEnvelopeFrom("<>");
/*     */     } else {
/* 459 */       mailSender.setEnvelopeFrom(account.getName());
/*     */     }
/* 461 */     mailSender.setDsnNotifyOptions(new MailSender.DsnNotifyOption[] { MailSender.DsnNotifyOption.NEVER });
/* 462 */     mailSender.sendMimeMessage(octxt, mailbox, notification);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static String getCharset(Account account, String data)
/*     */   {
/* 477 */     if ("us-ascii".equals(CharsetUtil.checkCharset(data, "us-ascii"))) {
/* 478 */       return "us-ascii";
/*     */     }
/* 480 */     return CharsetUtil.checkCharset(data, account.getAttr("zimbraPrefMailDefaultCharset", "utf-8"));
/*     */   }
/*     */   
/*     */   static String truncateBodyIfRequired(String body, int maxBodyBytes)
/*     */   {
/*     */     try {
/* 486 */       byte[] bodyBytes = body.getBytes("utf-8");
/* 487 */       if ((maxBodyBytes > -1) && (bodyBytes.length > maxBodyBytes))
/*     */       {
/*     */ 
/*     */ 
/* 491 */         int indexToExclude = maxBodyBytes;
/* 492 */         while ((indexToExclude > 0) && (bodyBytes[indexToExclude] < -64)) {
/* 493 */           indexToExclude--;
/*     */         }
/* 495 */         return new String(bodyBytes, 0, indexToExclude, "utf-8");
/*     */       }
/*     */     } catch (UnsupportedEncodingException e) {
/* 498 */       ZimbraLog.filter.error("Error while truncating body", e);
/*     */     }
/* 500 */     return body;
/*     */   }
/*     */   
/*     */   @VisibleForTesting
/*     */   static Map<String, String> getVarsMap(Mailbox mailbox, ParsedMessage parsedMessage, MimeMessage mimeMessage) throws MessagingException, ServiceException
/*     */   {
/* 506 */     Map<String, String> vars = new HashMap()
/*     */     {
/*     */       public String get(Object key) {
/* 509 */         return (String)super.get(((String)key).toLowerCase());
/*     */       }
/* 511 */     };
/* 512 */     Enumeration enumeration = mimeMessage.getAllHeaders();
/* 513 */     while (enumeration.hasMoreElements()) {
/* 514 */       Header header = (Header)enumeration.nextElement();
/* 515 */       vars.put(header.getName().toLowerCase(), ZInternetHeader.decode(mimeMessage.getHeader(header.getName(), ",")));
/*     */     }
/*     */     
/*     */ 
/* 519 */     vars.put("subject", parsedMessage.getSubject());
/* 520 */     MPartInfo bodyPart = Mime.getTextBody(parsedMessage.getMessageParts(), false);
/* 521 */     if (bodyPart != null) {
/*     */       try {
/* 523 */         vars.put("body", Mime.getStringContent(bodyPart.getMimePart(), mailbox.getAccount().getPrefMailDefaultCharset()));
/*     */       }
/*     */       catch (IOException e) {
/* 526 */         ZimbraLog.filter.warn("Error in reading text body", e);
/*     */       }
/*     */     }
/* 529 */     return vars;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   private static MimeMessage createRedirectMsgOnError(MimeMessage originalMsg)
/*     */     throws MessagingException
/*     */   {
/* 538 */     new Mime.FixedMimeMessage(originalMsg)
/*     */     {
/*     */       protected void updateHeaders() throws MessagingException {
/* 541 */         setHeader("MIME-Version", "1.0");
/* 542 */         updateMessageID();
/*     */       }
/*     */     };
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   private static boolean isMailLoop(Mailbox sourceMbox, MimeMessage msg)
/*     */     throws ServiceException
/*     */   {
/* 553 */     String[] forwards = Mime.getHeaders(msg, "X-Zimbra-Forwarded");
/* 554 */     String userName = sourceMbox.getAccount().getName();
/* 555 */     for (String forward : forwards) {
/* 556 */       if (StringUtil.equal(userName, forward)) {
/* 557 */         return true;
/*     */       }
/*     */     }
/* 560 */     return false;
/*     */   }
/*     */   
/*     */   public static int getFlagBitmask(Collection<ActionFlag> actions, int startingBitMask) {
/* 564 */     int bitmask = startingBitMask;
/* 565 */     for (ActionFlag action : actions) {
/* 566 */       if (action.isSet()) {
/* 567 */         bitmask |= action.getFlag().toBitmask();
/*     */       } else {
/* 569 */         bitmask &= (action.getFlag().toBitmask() ^ 0xFFFFFFFF);
/*     */       }
/*     */     }
/* 572 */     return bitmask;
/*     */   }
/*     */   
/*     */   public static String[] getTagsUnion(String[] tags1, String[] tags2) {
/* 576 */     if (tags2 == null)
/* 577 */       return tags1;
/* 578 */     if (tags1 == null) {
/* 579 */       return tags2;
/*     */     }
/*     */     
/* 582 */     Set<String> tags = Sets.newHashSet(tags1);
/* 583 */     tags.addAll(Arrays.asList(tags2));
/* 584 */     return (String[])tags.toArray(new String[tags.size()]);
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/filter/FilterUtil.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */